package eerbaar.shared.persist.internal.lib;

import java.util.List;

import eerbaar.context.IParams;
import eerbaar.expression.ExpressionFactory;
import eerbaar.expression.IExpression;
import eerbaar.shared.exceptions.GameException;
import eerbaar.shared.exceptions.GameRuntimeException;
import eerbaar.shared.persist.IPersistService;
import eerbaar.shared.persist.IPersister;
import eerbaar.shared.persist.ISaver;
import eerbaar.shared.service.ServiceFactory;
import eerbaar.shared.tree.IAttributes;
import eerbaar.shared.tree.INode;
import eerbaar.shared.tree.NodeCmdFactory;

public class ExpressionPersister implements IPersister<IExpression> {

    public static final String NAME = "expression";

    private IExpression target;

    public ExpressionPersister() {
        //
    }

    public ExpressionPersister(IExpression target) {
        this.target = target;
    }

    public ExpressionPersister(INode node) throws GameRuntimeException {
        load(node);
    }

    @Override
    public Class<IExpression> getRegistertedInterface() {
        return IExpression.class;
    }

    @Override
    public ISaver<?>[] getSavableChildren() {

        IParams params = this.target.getParams();
        ParamsPersister p = new ParamsPersister(params);
        return new ISaver<?>[] { p };
    }

    @Override
    public String getSavableName() {

        return NAME;
    }

    @Override
    public IExpression getTarget() {
        return this.target;
    }

    @Override
    public boolean isAssignableFrom(ISaver<?> saver) {
        return false;
    }

    @Override
    public IExpression load(INode node) {
        assert (node != null);

        IAttributes attributes = node.getAttributes();
        String type = attributes.get(String.class, "type");

        IPersistService service = ServiceFactory
                .getService(IPersistService.class);

        IParams params = null;
        List<INode> list = NodeCmdFactory.findChildren(node,
                ParamsPersister.NAME);
        for (INode n : list) {
            try {
                params = service.load(IParams.class, n);
            } catch (GameException e) {
                e.printStackTrace();
            }
        }

        IExpression result = ExpressionFactory.createExpression(type, params);
        return result;
    }

    @Override
    public void saveAttributes(INode node) {

        IAttributes a = node.getAttributes();

        String type = this.target.getType();
        a.set(String.class, "type", type);

        IParams params = this.target.getParams();
        String[] names = this.target.getParamNames();
        for (String name : names) {
            String value = params.get(name);
            a.set(String.class, name, value);
        }
    }

    @Override
    public void setTarget(IExpression obj) {
        this.target = obj;
    }

}
